package FanXingT;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 查看泛型
 * 通过 签名信息。
 *
 * getGenericSuperclass
 *
 */
public class GetTClass {
	public static void main(String[] args) {
      Base<User> base = new Base<User>() {};

      ParameterizedType superType = (ParameterizedType) base.getClass().getGenericSuperclass();
      for (Type ty:superType.getActualTypeArguments()) {
          System.out.println("getGenericSuperclass:"+ty+"  :"+ty.getTypeName());//TODO 得到泛型：class FanXingT.User
      }

      Method[] methods = base.getClass().getSuperclass().getDeclaredMethods();
      for (Method md:methods) {
          System.out.println("");
          System.out.println("method: tostring:--->"+md.toString());

          System.out.println("入参参数类型：");
          Type[] genericParameterTypes = md.getGenericParameterTypes();
          for (Type genericParameterType : genericParameterTypes) {
              System.out.println("type:"+genericParameterType);
              //ParameterizedType:表示一种参数化类型，比如Collection<Object>
              if(genericParameterType instanceof ParameterizedType){
                  Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                  for (Type parameterType : actualTypeArguments) {
                      System.out.println(parameterType);
                  }
              }
          }

          System.out.println("返回值 参数类型：");
          //获取方法的返回值类型
          Type genericReturnType = md.getGenericReturnType();//return type
          System.out.println("type: "+genericReturnType);
          if(genericReturnType instanceof ParameterizedType){
              Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
              for (Type parameterType : actualTypeArguments) {
                  System.out.println(parameterType);
              }
          }
      }

  }
}

abstract class Base<T>{
	  //获取T的Class对象是关键，看构造方法
    private Class<T> cls = null;
	  Base() {
        //为了得到T的Class，采用如下方法
        //1得到该泛型类的子类对象的Class对象
        Class clz = this.getClass();
        //2得到子类对象的泛型父类类型（也就是BaseDaoImpl<T>）
        ParameterizedType type = (ParameterizedType) clz.getGenericSuperclass();
        System.out.println("Constructor get <T> getGenericSuperclass: "+type);// print: FanXingT.Base<FanXingT.User>


        Type[] types = type.getActualTypeArguments();
        cls = (Class<T>) types[0];
        System.out.println("Constructor get <T> getGenericSuperclass.getActualTypeArguments[0]: "+cls.getName());//print:  FanXingT.User

    }

    Map<Integer,String> getMap(List<Double> input,List<User> users){
        return null;
    }
}

class User{
	String name;
	int age;
}
